package com.stylesmile.socket.aio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class AsyncHttpServer2 {
    private static final int PORT = 8080;
    /**
     * cpu count
     */
    private static int corePoolSize = Runtime.getRuntime().availableProcessors();

    /**
     * 创建线程池  调整队列数 拒绝服务
     */
    private static ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, corePoolSize * 10, 500L, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(2000));

    public static void main(String[] args) throws IOException {
        AsynchronousServerSocketChannel serverChannel = AsynchronousServerSocketChannel.open();
        InetSocketAddress address = new InetSocketAddress(PORT);
        serverChannel.bind(address);

        System.out.println("Server started on port " + PORT);

        serverChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
            @Override
            public void completed(AsynchronousSocketChannel socketChannel, Void attachment) {
                serverChannel.accept(null, this); // Accept the next connection
                handleClient(socketChannel);
//                executor.submit(() -> serverChannel.accept(null, this));
//                executor.submit(() -> handleClient(socketChannel));
            }

            @Override
            public void failed(Throwable exc, Void attachment) {
//                System.out.println("Failed to accept a connection");
            }
        });

        // Keep the server running until interrupted
        try {
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            serverChannel.close();
        }
    }

    private static void handleClient(AsynchronousSocketChannel socketChannel) {
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        Future<Integer> readResult = socketChannel.read(buffer);

        try {
            readResult.get();
            buffer.flip();
            String request = new String(buffer.array(), 0, buffer.limit());
//            System.out.println("Received request: " + request);

            // Process the request and send response
            String response = "HTTP/1.1 200 OK\r\nContent-Length: 13\r\n\r\nHello, World!";
            ByteBuffer responseBuffer = ByteBuffer.wrap(response.getBytes());
            Future<Integer> writeResult = socketChannel.write(responseBuffer);
            writeResult.get();

            socketChannel.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
